package com.lcq.gulimall.ware.service.impl;

import com.lcq.common.constant.WareConstant;
import com.lcq.gulimall.ware.entity.PurchaseDetailEntity;
import com.lcq.gulimall.ware.service.PurchaseDetailService;
import com.lcq.gulimall.ware.service.WareSkuService;
import com.lcq.gulimall.ware.vo.PurchaseDetailDoneVo;
import com.lcq.gulimall.ware.vo.PurchaseDoneVo;
import com.lcq.gulimall.ware.vo.PurchaseMergeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lcq.common.utils.PageUtils;
import com.lcq.common.utils.Query;

import com.lcq.gulimall.ware.dao.PurchaseDao;
import com.lcq.gulimall.ware.entity.PurchaseEntity;
import com.lcq.gulimall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {
    @Autowired
    PurchaseDetailService purchaseDetailService;

    @Autowired
    WareSkuService wareSkuService;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils unreceiveList(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>().eq("status",
                        WareConstant.PurchaseStatusEnum.CREATED.getCode()).or()
                        .eq("status",WareConstant.PurchaseStatusEnum.ASSIGNED.getCode())
        );
        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void merge(PurchaseMergeVo purchaseMergeVo) {
        Long[] ids = purchaseMergeVo.getItems();
        if(ids==null&&ids.length==0){
            return;
        }
        Long pId = purchaseMergeVo.getPurchaseId();
        PurchaseEntity pEntity = null;
        if(pId==null){
            pEntity = new PurchaseEntity();
            pEntity.setCreateTime(new Date());
            pEntity.setUpdateTime(new Date());
            pEntity.setPriority(1);
            pEntity.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());
            this.save(pEntity);
            pId = pEntity.getId();
        }else {
            pEntity = this.getById(pId);
            /**
             * 不是创建和分配状态的采购单不能被合并
             *
             * */
            if (pEntity.getStatus()!=WareConstant.PurchaseStatusEnum.CREATED.getCode() &&
                    pEntity.getStatus()!=WareConstant.PurchaseStatusEnum.ASSIGNED.getCode()){
                return;
            }
        }

        Long finalPId = pId;
        List<PurchaseDetailEntity> pList = Arrays.stream(ids).map((id)->{
            PurchaseDetailEntity ppEntity = new PurchaseDetailEntity();
            ppEntity.setId(id);
            ppEntity.setPurchaseId(finalPId);
            ppEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode());
            return ppEntity;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(pList);

        pEntity = new PurchaseEntity();
        pEntity.setId(pId);
        pEntity.setUpdateTime(new Date());
        this.updateById(pEntity);
        return;
    }

    @Override
    public void saveDetail(PurchaseEntity purchase) {
        purchase.setCreateTime(new Date());
        purchase.setUpdateTime(new Date());
        this.save(purchase);
    }

    @Override
    public void update(PurchaseEntity purchase) {
        Long id = purchase.getAssigneeId();
        Integer status = purchase.getStatus();
        if(status!=null && status==1 && (id==null||id==0)){
            return;
        }
        this.updateById(purchase);
    }

    @Transactional
    @Override
    public void received(List<Long> ids) {
        if(ids==null||ids.size()==0){
            return;
        }
        List<PurchaseDetailEntity> detailUpdateEntities = new ArrayList<>();
        List<PurchaseEntity> entities = this.getBaseMapper().selectBatchIds(ids);
        if (entities!=null&&entities.size()!=0){
            List<PurchaseEntity> updateEntities =  entities.stream().filter((entity)->{
              return entity.getStatus()==WareConstant.PurchaseStatusEnum.ASSIGNED.getCode();
            }).map((entity)->{
                entity.setStatus(WareConstant.PurchaseStatusEnum.RECEIVED.getCode());
                entity.setUpdateTime(new Date());
                List<PurchaseDetailEntity> list = purchaseDetailService.getBaseMapper().selectList(
                        new QueryWrapper<PurchaseDetailEntity>().eq("purchase_id",entity.getId()));
                if(list!=null&&list.size()>0){
                    list.stream().forEach(e->{
                        e.setStatus(WareConstant.PurchaseDetailStatusEnum.PURCHASING.getCode());
                        detailUpdateEntities.add(e);
                    });
                }
                return entity;
            }).collect(Collectors.toList());

            this.updateBatchById(updateEntities);
            purchaseDetailService.updateBatchById(detailUpdateEntities);
        }
    }

    @Transactional
    @Override
    public void done(PurchaseDoneVo doneVo) {
        Long id = doneVo.getId();
        if(id==null||id==0){
            return;
        }

        PurchaseDetailDoneVo[] detailDoneVos = doneVo.getItems();
        if(detailDoneVos==null||detailDoneVos.length==0){
            return;
        }
        PurchaseEntity purchaseEntity = this.getById(id);
        purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.FINISHED.getCode());

        List<PurchaseDetailEntity> detailEntities = Arrays.stream(detailDoneVos).map((detailDoneVo)->{
            PurchaseDetailEntity entity = purchaseDetailService.getById(detailDoneVo.getItemId());
            if(entity!=null){
                entity.setId(detailDoneVo.getItemId());
                entity.setStatus(detailDoneVo.getStatus());
                if(entity.getStatus()==WareConstant.PurchaseStatusEnum.FINISHED.getCode()){
                    wareSkuService.add(entity.getSkuId(),entity.getWareId(),entity.getSkuNum());
                }else {
                    purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.ERROR.getCode());
                }
            }
            return entity;
        }).collect(Collectors.toList());

        purchaseDetailService.updateBatchById(detailEntities);
        purchaseEntity.setUpdateTime(new Date());
        this.updateById(purchaseEntity);
    }
}